#pragma once
#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>

// 协议
// "len"\r\n"{json}"\r\n --- 完整的报文， len 有效载荷的长度！
// \r\n: 区分len 和 json 串
// \r\n: 暂是没有其他用，打印方便，debug

const static std::string sep = "\r\n";

// 用于解析 请求字符串
// 从数据流队列中分割读取出完整的请求
std::string Decode(std::string &packagestream)
{
    auto pos = packagestream.find(sep);

    if (pos == std::string::npos)
        return std::string();

    std::string lenstr = packagestream.substr(0, pos);
    int len = std::stoi(lenstr);
    int total = lenstr.size() + sep.size() * 2 + len;

    if (total < packagestream.size())
        return std::string();

    // 有完整的请求, 可以提取报文
    std::string jsonstr = packagestream.substr(lenstr.size() + sep.size(), total);
    packagestream.erase(0, total); // 去除已经被提取的部分

    return jsonstr;
}

// 添加报头
std::string Encode(const std::string &jsonstr)
{
    int len = jsonstr.size();
    std::string lenstr = std::to_string(len);

    return lenstr + sep + jsonstr + sep;
}

class Request
{
public:
    Request()
    {
    }
    Request(int x, int y, char oper)
        : _x(x), _y(y), _oper(oper)
    {
    }
    ~Request()
    {
    }

    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;

        Json::FastWriter writer;
        // Json::StyledWriter writer;
        std::string s = writer.write(root);
        *out = s;

        return true;
    }

    bool DeSerialize(const std::string &jsonstr)
    {
        Json::Reader reader;
        Json::Value root;

        if (!reader.parse(jsonstr, root))
        {
            std::cout << "解析失败" << std::endl;
            return false;
        }

        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt();

        return true;
    }

    void Analysis(const std::string &str)
    {
        int pos = 0;
        for (int i = 0; i < str.length(); i++)
        {
            if (str[i] > '9' || str[i] < '1')
            {
                pos = i;
                break;
            }
        }
        std::string str_x = str.substr(0, pos);
        std::string str_y = str.substr(pos + 1);

        _x = std::stoi(str_x);
        _y = std::stoi(str_y);
        _oper = str[pos];
    }

    int X()
    {
        return _x;
    }
    int Y()
    {
        return _y;
    }
    char Oper()
    {
        return _oper;
    }
    void SetValue(int x, int y, char oper)
    {
        _x = x;
        _y = y;
        _oper = oper;
    }

private:
    int _x;
    int _y;
    char _oper;
};

class Response
{
public:
    Response()
        : _result(0), _code(0), _desc("success")
    {
    }
    ~Response() {}

    bool Serialize(std::string *out)
    {
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        root["desc"] = _desc;

        Json::FastWriter writer;
        // Json::StyledWriter writer;
        std::string s = writer.write(root);
        *out = s;

        return true;
    }

    bool DeSerialize(const std::string &jsonstr)
    {
        Json::Reader reader;
        Json::Value root;

        if (!reader.parse(jsonstr, root))
        {
            std::cout << "解析失败" << std::endl;
            return false;
        }

        _result = root["result"].asInt();
        _code = root["code"].asInt();
        _desc = root["desc"].asString();

        return true;
    }

    void PrintResult()
    {
        std::cout << "result: " << _result << ", code: " << _code << ", desc: " << _desc << std::endl;
    }

public:
    int _result;
    int _code; // 0: 成功 1: 除0操作 2:非法操作
    std::string _desc;
};

// 工厂模式
class Factory
{
public:
    static std::shared_ptr<Request> BuildRequestDefault()
    {
        return std::make_shared<Request>();
    }
    static std::shared_ptr<Response> BuildResponseDefault()
    {
        return std::make_shared<Response>();
    }
};